package com.ewei.support.javax.mail;

import java.security.GeneralSecurityException;
import java.security.Provider;
import java.security.Security;
import java.util.Properties;

import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;

import org.budo.support.lang.util.ReflectUtil;
import org.budo.support.lang.util.SystemUtil;
import org.budo.support.slf4j.Slf4j;
import org.slf4j.Logger;

import com.sun.mail.smtp.SMTPTransport;
import com.sun.mail.util.MailSSLSocketFactory;

/**
 * @author lmw
 */
public class MailSessionUtil {
    private static final Logger log = Slf4j.getLogger();

    public static Session getSmtpSession(String host, String email, String password, boolean isSsl, Integer port) {
        Properties properties = new Properties();
        properties.put("mail.smtp.host", host);
        properties.put("mail.transport.protocol", "smtp");
        if (isSsl) {
            properties.put("mail.smtp.ssl.enable", "true");
            MailSSLSocketFactory mailSSLSocketFactory = null;
            try {
                mailSSLSocketFactory = new MailSSLSocketFactory();
                mailSSLSocketFactory.setTrustAllHosts(true);
                properties.put("mail.smtp.ssl.socketFactory", mailSSLSocketFactory);
            } catch (GeneralSecurityException e) {
                log.error("" + e, e);
            }
            properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            properties.put("mail.smtp.socketFactory.fallback", "false");
        }
        if (null == port || port <= 0) {
            if (isSsl) {
                properties.put("mail.smtp.port", "465");
                properties.put("mail.smtp.socketFactory.port", "465");
            } else {
                properties.put("mail.smtp.port", "25");
                properties.put("mail.smtp.socketFactory.port", "25");
            }
        } else {
            properties.put("mail.smtp.port", port);
            properties.put("mail.smtp.socketFactory.port", port);
        }
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.connectiontimeout", "15000");
        properties.put("mail.smtp.timeout", "15000");
        Session session = Session.getInstance(properties, new PasswordAuthenticator(email, password));
        return session;
    }

    public static Session getSession(String protocol, String host, boolean isSsl, Integer port) throws GeneralSecurityException {
        Properties properties = SystemUtil.getProperties();
        if (isSsl) {
            Class sslProviderType = ReflectUtil.classForName("com.sun.net.ssl.internal.ssl.Provider"); // jdk10中没有这个类
            Provider sslProvider = (Provider) ReflectUtil.newInstance(sslProviderType);
            Security.addProvider(sslProvider);
            MailSSLSocketFactory mailSSLSocketFactory = new MailSSLSocketFactory();
            mailSSLSocketFactory.setTrustAllHosts(true);
            properties.setProperty("mail." + protocol + ".ssl.enable", "true");
            properties.put("mail." + protocol + ".ssl.socketFactory", mailSSLSocketFactory);
            properties.setProperty("mail." + protocol + ".socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            properties.setProperty("mail." + protocol + ".socketFactory.fallback", "false");
            properties.setProperty("mail.store.protocol", protocol);
            properties.setProperty("mail." + protocol + ".host", host);

            if (null != port && port > 0) {
                properties.setProperty("mail." + protocol + ".port", port + "");
                properties.setProperty("mail." + protocol + ".socketFactory.port", port + "");
            }
        } else {
            properties.setProperty("mail.store.protocol", protocol);
            properties.setProperty("mail." + protocol + ".host", host);
            if (null != port && port > 0) {
                properties.setProperty("mail." + protocol + ".port", port + "");
            }
        }
        properties.setProperty("mail." + protocol + ".disabletop", "true");
        properties.setProperty("mail." + protocol + ".useStartTLS", "true");

        properties.setProperty("mail." + protocol + ".timeout", "15000");
        properties.setProperty("mail." + protocol + ".connectiontimeout", "15000");

        Session session = Session.getInstance(properties);
        return session;
    }

    public static Boolean isSmtp(Session session, InternetAddress fromAddress) {
        Transport transport = null;
        try {
            transport = session.getTransport(fromAddress);
            return transport instanceof SMTPTransport;
        } catch (NoSuchProviderException e) {
            throw new RuntimeException("NoSuchProviderException, fromAddress=" + fromAddress + ", e=" + e, e);
        } finally {
            TransportUtil.close(transport);
        }
    }
}